#include "head.h"

// 客户端用户输入puts命令的调用函数
// 第一个参数：客户端用户和服务端网络通信的socket对象fd
// 第二个参数：puts 文件名  命令中的文件名
int sendFile(int socket_fd, transport_protocol_t *msg)
{
    char file_name[60];
    memset(file_name,0,sizeof(file_name));
    strcpy(file_name,msg->buf);
    send(socket_fd,&file_name,sizeof(file_name),MSG_NOSIGNAL);

    int exit_flag = 0;
    printf("----------\n");
    recv(socket_fd,&exit_flag,sizeof(int),MSG_WAITALL);
    if(exit_flag != 0){
        printf("该目录下已有同名文件!\n");
        return 0;
    }
    
    // 打开要上传的文件
    int file_fd = open(msg->buf, O_RDWR);
    int is_file = 0;
    if(file_fd == -1){
        printf("本地没有此文件\n");
        //通知服务端
        is_file = -1;
        send(socket_fd,&is_file,sizeof(int),MSG_NOSIGNAL);
        close(file_fd);
        return 0;
    }
    send(socket_fd,&is_file,sizeof(int),MSG_NOSIGNAL);

    // 获取文件的hash值，发送给服务端
    char hash_val[100];
    getHash(msg->buf, hash_val);
    //printf("HASH:%s\n",hash_val);
    send(socket_fd, hash_val, sizeof(hash_val), MSG_NOSIGNAL);
    
    // 获取文件大小
    struct stat st;
    memset(&st, 0, sizeof(st));
    fstat(file_fd, &st);
    printf("获取本地文件大小：%ld\n",st.st_size);

    // 上传文件前先接受服务端传输过来的已上传的文件大小
    off_t updated_size = 0;
    recv(socket_fd, &updated_size, sizeof(off_t), MSG_WAITALL);
    printf("服务端已上传的文件大小:%ld\n", updated_size);

    // updated_num 表示已下载文件对页大小4096取整的页数
    int updated_num = updated_size / 4096;

    // 服务端已有上传完整的文件
    if (updated_size == st.st_size)
    {
        char buf[100];
        recv(socket_fd, buf, sizeof(buf), MSG_WAITALL);
        // 输出收到服务端发送的提示信息
        printf("%s\n", buf);
        close(file_fd);
        
        return 0;
    }

    // 已上传文件大小为0
    if (updated_size == 0)
    {
        // 把文件大小发送给服务端
        send(socket_fd, &st.st_size, sizeof(off_t), MSG_NOSIGNAL);

        // 使用sendfile: 零拷贝
        sendfile(socket_fd, file_fd, NULL, st.st_size);

        char buf[100];
        recv(socket_fd, buf, sizeof(buf), MSG_WAITALL);
        // 输出收到服务端发送的提示信息
        printf("%s\n", buf);

        // printf("close \n");
        close(file_fd);
        
        return 0;
    }

    // 已上传文件大小不为0也不是完整大小，把续传的文件大小发送给服务端
    off_t send_size = st.st_size - updated_num * 4096;
    send(socket_fd, &send_size, sizeof(off_t), MSG_NOSIGNAL);

    // 使用sendfile: 零拷贝
    off_t off_set = (off_t)updated_num * 4096; // off_set偏移量
    sendfile(socket_fd, file_fd, &off_set, send_size);

    char buf[100];
    recv(socket_fd, buf, sizeof(buf), MSG_WAITALL);
    // 输出收到服务端发送的提示信息
    printf("%s\n", buf);

    //printf("close \n");
    close(file_fd);
    
    return 0;
}
